package testing;

import processing.core.*;
import processing.xml.*;
import testing.testView.Element;

import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;

import Shapes.Node;

public class pieTree extends PApplet {

	int selectfather = -1;
	int selectMinLevel = 10;
	int selectMaxLevel = -1;
	public String filename = "";
	PFont fontA;
	
	public ArrayList<pie> pieTree = new ArrayList<pie>();

	public void setup()
	{
	  size(400, 400);
	  noStroke(); 
	  smooth();

//	  this.generateTree("../resource/con1997.txt");
	  
	  fontA = loadFont("../resource/Ziggurat-32.vlw");

		// Set the font and its size (in units of pixels)
	  textFont(fontA, 20);
	  //testing data
	  
	  pie p1 = new pie();
	  p1.father = -1;
	  p1.arc = new Arc(this.width/2,this.height/2,140,0, PI/4,0.9f,8.0f,0.1f,0,0+"");
	  p1.level = 1;
	  pieTree.add(p1);
	  
	  pie p2 = new pie();
	  p2.father = -1;
	  p2.arc = new Arc(this.width/2,this.height/2,140,PI/4+0.02f,3*PI/4-0.02f,0.9f,8.0f,0.1f,1,1+"");
	  p2.level = 1;
	  pieTree.add(p2);
	  
	  pie p3 = new pie();
	  p3.father = -1;
	  p3.arc = new Arc(this.width/2,this.height/2,140,PI+0.02f,PI,0.9f,8.0f,0.1f,2,2+"");
	  p3.level = 1;
	  pieTree.add(p3);
	  
	  pie p31 = new pie();
	  p31.father = 2;
	  p31.arc = new Arc(this.width/2,this.height/2,200,PI+0.02f,PI/2-0.02f,0.9f,8.0f,0.1f,3,3+"");
	  p31.level = 2;
	  pieTree.add(p31);
	  
	  pie p32 = new pie();
	  p32.father = 2;
	  p32.arc = new Arc(this.width/2,this.height/2,200,3*PI/2,PI/2,0.9f,8.0f,0.1f,4,4+"");
	  p32.level = 2;
	  pieTree.add(p32);
	  
	  pie p321 = new pie();
	  p321.father = 4;
	  p321.arc = new Arc(this.width/2,this.height/2,280,3*PI/2,PI/4,0.9f,8.0f,0.1f,5, 5+"");
	  p321.level = 3;
	  pieTree.add(p321);
	  
	  pie p322 = new pie();
	  p322.father = 4;
	  p322.arc = new Arc(this.width/2,this.height/2,280,7*PI/4,PI/4,0.9f,8.0f,0.1f,6, 6+"");
	  p322.level = 3;
	  pieTree.add(p322);
	  
	  
	}

	private void generateTree(String filename) {
		// TODO Auto-generated method stub
		readFile rf = new readFile(this);
		rf.setup(filename);
		rf.load();
		int num = rf.getLength();
		int piece = rf.getPieceNum();
		float sum = 0.0f;
		for(int i = 1; i<num; i ++){
			String[] pieces = split(rf.lines[i], '\t');
			sum += parseFloat(pieces[1]);
		}
		
		float cal = 0.0f;
		for(int i = 1; i <num; i++){
			
			String[] pieces = split(rf.lines[i], '\t');
			
			pie p = new pie();
			p.father = -1;
			p.name = pieces[0];
			float part = parseFloat(pieces[1]);
			float angle = part*2*PI/sum;
			p.arc = new Arc(this.width/2,this.height/2,400,cal,angle,0.9f,8.0f,0.1f,i-1,p.name);
			p.level = 1;
			pieTree.add(p);
			
			cal += angle;
		}
		
	}

	public void draw() {
		background(51);
		int temproot = this.selectfather;

		while (temproot != -2) {
			for (int i = 0; i < pieTree.size(); i++) {
				if (pieTree.get(i).father == temproot) {
					pieTree.get(i).arc.update();
					pieTree.get(i).arc.display();
				}
			}
			
			if(temproot == -1){
				temproot = -2;
			}else{
				temproot = pieTree.get(temproot).father;
			}
		}
		
	}

	public void mousePressed() 
	{
	  for (int i = 0; i < pieTree.size(); i++) { 
		 pieTree.get(i).arc.pressed();
	  } 
	}

	public void mouseReleased() 
	{
		for (int i = 0; i < pieTree.size(); i++) { 
			 pieTree.get(i).arc.released();
		   
		  } 
	 
	}

	class Arc {
		// Screen values
		float xpos, ypos;
		float temp_size;
		int size = 20;
		float start = 0;
		float angle = 0;
		boolean over = false;
		boolean move = false;
		int id;

		// Spring simulation constants
		float mass; // Mass
		float k = 0.2f; // Spring constant
		float damp; // Damping
		float rest_size; // Rest position X
		

		// Spring simulation variables
		// float pos = 20.0; // Position
		float velx = 0.0f; // X Velocity
		float vely = 0.0f; // Y Velocity
		float accel = 0; // Acceleration
		float force = 0; // Force
		String name = "";

		int me;

		// Constructor
		Arc(float x, float y, int s, float t, float ang, float d, float m, float k_in, int id, String name) {
		
			xpos  = x;
			ypos  = y;
			size = s;
			temp_size = size;
			rest_size = size;
			
			damp = d;
			mass = m;
			k = k_in;
		
			me = id;
			start = t;
			angle = ang;	
			this.id = id;
			this.name = name;
			
		}

		public void update() {
			if (move) {
				for(int i = 0; i < pieTree.size();i++)
				{
					
					if(pieTree.get(i).father == id){
						pieTree.get(i).arc.rest_size = pieTree.get(i).arc.size*1.5f; 
						//
						if(pieTree.get(id).level> selectMaxLevel)
						{
							selectfather = id;
						}
					}
				}
				
				if(pieTree.get(id).level> selectMaxLevel){
					selectMaxLevel = pieTree.get(id).level;
				}
				
				if(pieTree.get(id).level> selectMinLevel){
					selectMinLevel = pieTree.get(id).level;
				}
			}

			force = -k * (temp_size - rest_size); // f=-ky
			accel = force / mass; // Set the acceleration, f=ma == a=f/m
			vely = damp * (vely + accel); // Set the velocity
			temp_size = temp_size + vely; // Updated position


			if ((over() || move)) {
				over = true;
			} else {
				over = false;
			}
		}

		// Test to see if mouse is over this spring
		public boolean over() {
		
			//judge
			float disx = mouseX - xpos;
			float disy = mouseY - ypos;
			
			if(Math.sqrt(disx*disx + disy*disy)> size/2.0)
			{
				return false;
			}
			
			int father = pieTree.get(id).father;
			
			if(father != -1){
				
				if(Math.sqrt(disx*disx + disy*disy)< pieTree.get(father).arc.size/2.0){
					return false;
				}
			}
			
			
			float ang = 0.0f;
			if(disy == 0){
				if(disx >=0)
				{
					ang = 0;
				}else{
					ang = PI;
				}
			}
			if(disx == 0){
				if(disy >= 0)
				{
					ang = PI/2;
				}else{
					ang = 3*PI/2;
				}
			}
				
			if(disy > 0)
			{
				if(disx >0){
					ang = (float) Math.atan(disy/disx);
				}else{
					ang = PI - (float) Math.atan(disy/(-disx));
				}
				
			}else if(disy<0){
				
				if(disx<0){
					ang = PI +(float)Math.atan(disy/disx);
				}else{
					ang = 2*PI - (float)Math.atan(disy/(-disx));
				}
			}
		
				
			if((start < ang)&&(ang<(start + angle)))
			{
			
				return true;
				
			}else{
				return false;
			}
		}

		
		public void display() {
			if (over) {
				fill(153);
			} else {
				fill(id*10, id*30, id*50);
			}
			smooth();
		//	noStroke();
		//	fill(id * 50);
		  
        //  color(PApplet.parseInt(random(255)), PApplet.parseInt(random(255)), PApplet.parseInt(random(255)));
		   arc(xpos, xpos, temp_size, temp_size, start, start + angle);
			
		   if (over) {
				fill(255);
				text(name, mouseX, mouseY);
			} else {
		
			}

		}

		public void pressed() {
			if (over) {
				move = true;
				if(id == 4)
				{
					int a = 0;
				}
			} else {
				move = false;
			}
		}

		public void released() {
			move = false;
			rest_size = size;
		}
	}
	
//used to record the material flow inventory tree	
class pie{
	int father; // the node of this leave, the root's father == -1
	String name = "";
    Arc arc;
    int level;
}


}
